import Watcher from './Watcher.js';
export default class Compile{
	constructor(el,vue){
		console.log('compile类中=》',el);
		//vue实例
		this.$vue = vue;
		//挂在点
		this.$el = document.querySelector(el);
		//如果用户传入了挂载点
		if(this.$el){
			//调用函数让节点转换成fragment,这里的fragment类似mutache中的tokes。
			//实际上用的是AST，但这里就是轻量级级的fragment
			let $fragment = this.node2Fragment(this.$el);
			// 编译
			this.compile($fragment);
			//让虚拟dom上树
			this.$el.appendChild($fragment);
		}

	}
	node2Fragment(elNode){
		let fragment = document.createDocumentFragment();
		// console.log('fragment这个虚拟节点对象是：',fragment,elNode);
		// 让所有dom节点都进入中国虚拟节点对象fragment中
		let child;
		while(child = elNode.firstChild){
			fragment.appendChild(child);
			// console.count('计数');
			// console.log(child)
		};
		// console.log(fragment);
		return fragment
	}
	compile(fragment){
		//匹配{{}}语法的正则
		let reg = /\{\{(.*)\}\}/;
		var childNodes = fragment.childNodes;
		// console.log(fragment,childNodes);
		childNodes.forEach((node,index)=>{
			if(node.nodeType==1){
				console.log('是div元素')
				//如果nodetype是1是div元素就要调用compileElement函数进行进一步编译
				this.compileElement(node);
			}else if(node.nodeType==3 && reg.test(node.nodeValue)){
				let regValue = node.nodeValue.match(reg)[1];
				console.log('是text元素=>',regValue);
				this.compileText(node,regValue);
			}
		})

	}
	compileElement(node){
		console.log('我是compileElememnt函数');
		//这里的方便之处是和AST或tokens比，不是将节点看成字符串，而是一个节点对象，这样就可以方便获得属性列表
		let nodeAttrs = node.attributes;
		//将类数组对象转化成数组，下面代码和Array.prototype.slice.call(nodeAttrs)等价
		let nodeAttrsArr =[].slice.call(nodeAttrs);
		// console.log(nodeAttrsArr);
		nodeAttrsArr.forEach(item=>{
			//这里开始复习指令
			let attrName = item.name;
			let attrValue = item.value;
			//指令
			let dir = attrName.substring(2);
			if(attrName.indexOf('v-')>-1){
				if(dir=='model'){
					//数据的改变触发input值的改
					new Watcher(this.$vue,attrValue,(value)=>{
						node.value=value
					});
					//获取数据的值并渲染进input的value中
					let value = this.getVueVal(attrValue);
					node.value = value;
					console.log('是model指令',attrValue);
					//监听input时间来改变对应的数据
					node.addEventListener('input', ()=>{
						let newValue = node.value;
						this.setVueVal(attrValue,newValue);
						// console.log('1-------1=>',attrValue)
					});
				}else if(dir =='if'){
					console.log('是if指令')
				}
			}
		})
	}
	compileText(node,expression){
		let value = this.getVueVal(expression);	
		// console.log('expression=>',expression,value);	
		node.textContent=node.textContent.replace(/\{\{(.*)\}\}/,value);
		// console.log('compileText函数：',expression,this.getVueVal(expression));
		new Watcher(this.$vue,expression,(value,oldValue)=>{
			// this.compileText(node,expression);
			// console.log('Value====',value,'oldValue====',oldValue)
			// node.textContent =value;
			node.textContent=node.textContent.replace(/-?\d+/,value);
		})

	}
	getVueVal(expression){
		let val = this.$vue;
		let arr = expression.split('.');
		arr.forEach(item=>{
			val = val[item];
		});
		return val
	}
	setVueVal(expression,newValue){//p.o
	 // console.log('setVueVal函数中=》',expression,newValue)
		let val = this.$vue;
		let arr = expression.split('.');
		arr.forEach((item,index)=>{
			if(index<arr.length-1){
				val=val[item];
			}else{
				val[item] = newValue;
			}
		})

	}






















}